package com.zzz.system.service.sysUser.impl;

import cn.hutool.core.util.StrUtil;
import com.alibaba.nacos.common.utils.CollectionUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.github.pagehelper.PageHelper;
import com.zzz.common.core.constants.HttpConstants;
import com.zzz.common.core.domain.LoginUser;
import com.zzz.common.core.domain.R;
import com.zzz.common.core.enums.ResultCode;
import com.zzz.common.core.enums.UserIdentity;
import com.zzz.common.security.exception.ServiceException;
import com.zzz.common.security.service.TokenService;
import com.zzz.system.domain.systemUser.dto.SysUserSaveDTO;
import com.zzz.system.domain.systemUser.SystemUser;
import com.zzz.system.domain.systemUser.vo.LoginUserVo;
import com.zzz.system.domain.systemUser.vo.SysUserVo;
import com.zzz.system.domain.user.dto.UserQueryDTO;
import com.zzz.system.domain.user.vo.UserVO;
import com.zzz.system.domain.user.User;
import com.zzz.system.mapper.sysuser.SysUserMapper;
import com.zzz.system.mapper.user.UserMapper;
import com.zzz.system.service.sysUser.SysUserService;
import com.zzz.system.utils.BCryptUtils;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * @BelongsProject: oj-project
 * @BelongsPackage: com.zzz.system.service.sysUser.impl
 * @Author: zhai
 * @CreateTime: 2025-09-21  17:19
 * @Description: TODO 系统管理员服务实现类
 * @Version: 1.0
 */
@Slf4j
@Service
@RefreshScope
public class SysUserServiceImpl implements SysUserService {

    @Autowired
    private SysUserMapper sysUserMapper;

    @Autowired
    private UserMapper userMapper;

    @Resource
    private TokenService tokenService;

    @Value("${jwt.secret}")
    private String secret;

    /**
     * @description: 登录
     * @author: zhai
     * @date: 2025/9/22 12:43
     * @param: [userAccount, password]
     * @return: com.zzz.conmmon.core.domain.R<java.lang.String>
     **/
    @Override
    public R<String> login(String userAccount, String password) {
        log.info("用户登录：{}",userAccount.toString());
        LambdaQueryWrapper<SystemUser> queryWrapper = new LambdaQueryWrapper<>();
        SystemUser systemUser = sysUserMapper.selectOne(queryWrapper.select(SystemUser::getUserId,
                        SystemUser::getPassword,
                        SystemUser::getNickName)
                .eq(SystemUser::getUserAccount, userAccount));
        log.info("用户信息是：{}", systemUser);
        if (systemUser == null) {
            log.error("用户不存在");
            return R.fail(ResultCode.FAILED_USER_NOT_EXISTS.getMsg());
        }
        log.info("找到用户,id是：{}，开始校验密码", systemUser.getUserId() );
        if (BCryptUtils.matchesPassword(password, systemUser.getPassword())) {
            log.info("密码正确，开始生成token");
            String token = tokenService.createToken(systemUser.getUserId(), secret,
                    UserIdentity.ADMIN.getValue(), systemUser.getNickName(), null);
            log.info("缓存的信息是：{}", systemUser);
            if (token == null) {
                log.error("生成token失败");
                return R.fail(ResultCode.FAILED.getMsg());
            }
            log.info("用户登录成功，token是：{}", token);
            return R.success(token);
        }
        log.error("密码错误");
        return R.fail(ResultCode.FAILED_PASSWORD_ERROR.getMsg());
    }

    /**
     * @description: 添加系统用户
     * @author: zhai
     * @date: 2025/9/22 12:43
     * @param: [sysUserSaveDTO]
     * @return: com.zzz.conmmon.core.domain.R<java.lang.Void>
     **/
    @Override
    public int add(SysUserSaveDTO sysUserSaveDTO) {
        log.info("添加用户: {}，开始校验是否被注册过", sysUserSaveDTO.getUserAccount());
        LambdaQueryWrapper<SystemUser> queryWrapper = new LambdaQueryWrapper<>();
        List<SystemUser> sysUserList = sysUserMapper.selectList(queryWrapper.select(SystemUser::getUserAccount)
                .eq(SystemUser::getUserAccount, sysUserSaveDTO.getUserAccount()));
        if (CollectionUtils.isNotEmpty(sysUserList)) {
            log.error("用户已存在");
            throw new ServiceException(ResultCode.FAILED_USER_EXISTS);
        }
        log.info("用户不存在，开始添加");
        SystemUser newUser = new SystemUser();
        newUser.setUserAccount(sysUserSaveDTO.getUserAccount());
        newUser.setNickName(sysUserSaveDTO.getNickName());
        newUser.setPassword(BCryptUtils.encryptPassword(sysUserSaveDTO.getPassword()));
        log.info("开始插入用户");
        return sysUserMapper.insert(newUser);
    }

    /**
     * @description: 获取管理员信息（昵称）
     * @author: zhai
     * @date: 2025/10/14 16:48
     * @param: [token]
     * @return: com.zzz.common.core.domain.R<com.zzz.system.domain.systemUser.vo.LoginUserVo>
     **/
    @Override
    public R<LoginUserVo> info(String token) {
        // 如果前端设置了令牌前缀，则裁剪掉前缀
        if (StrUtil.isNotEmpty(token) && token.startsWith(HttpConstants.PREFIX)) {
            token = token.replaceFirst(HttpConstants.PREFIX, StrUtil.EMPTY);
        }
        // token: 头部 + 负载(claims{userKey+userId}) + 签名（secret）
        // redis: userKey + loginUser(UserIdentity.ADMIN)
        log.info("获取管理员信息：{}", token);
        LoginUser loginUser = tokenService.getLoginUser(token, secret);
        if (loginUser == null) {
            log.error("token错误");
            return R.fail(ResultCode.FAILED_TOKEN_ERROR.getMsg());
        }
        log.info("token正确，开始获取用户信息");
        LoginUserVo loginUserVo = new LoginUserVo();
        loginUserVo.setNickName(loginUser.getNickName());
        log.info("用户信息获取成功，用户昵称是：{}", loginUserVo.getNickName());
        return R.success(loginUserVo);
    }

    /**
     * @description: 登出
     * @author: zhai
     * @date: 2025/10/15 13:55
     * @param: [token]
     * @return: com.zzz.common.core.domain.R<java.lang.Void>
     **/
    @Override
    public R<Void> logout(String token) {
        boolean flag = tokenService.logout(token, secret);
        if (!flag) {
            log.error("登出失败");
            return R.fail();
        }
        return R.success();
    }

    /**
     * @description: 获取管理员详情
     * @author: zhai
     * @date: 2025/9/22 16:15
     * @param: [userId]
     * @return: com.zzz.conmmon.core.domain.R<com.zzz.system.domain.systemUser.SystemUser>
     **/
    @Override
    public R<SysUserVo> detail(Long userId) {
        return null;
    }

    /**
     * @description: 删除系统用户
     * @author: zhai
     * @date: 2025/9/22 16:15
     * @param: [userId]
     * @return: com.zzz.conmmon.core.domain.R<java.lang.Void>
     **/
    @Override
    public int delete(Long userId) {
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        List<User> userList = userMapper.selectList(queryWrapper.select(User::getUserId));
        if (CollectionUtils.isEmpty(userList)) {
            log.error("用户不存在，无法删除");
            throw new ServiceException(ResultCode.FAILED_USER_NOT_EXISTS);
        }
        int delete = userMapper.deleteById(userId);
        if (delete <= 0) {
            log.error("删除用户失败");
            throw new ServiceException(ResultCode.FAILED_DELETE);
        }
        log.info("删除用户成功");
        return delete;
    }

    /**
     * @description: 跟新系统用户信息
     * @author: zhai
     * @date: 2025/9/22 16:16
     * @param: [systemUser]
     * @return: com.zzz.conmmon.core.domain.R<com.zzz.system.domain.systemUser.SystemUser>
     **/
    @Override
    public R<SystemUser> update(SystemUser systemUser) {
        return null;
    }
}
